package com.rpc.rpcservercontainer;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.rpc.rpcservercontainer.PackageReader.RpcPackage;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipException;
import org.apache.log4j.Logger;

/**
 * Simple class containing the main method for the RPCServerContainer.
 */
public class App 
{
    private static final Logger log = Logger.getLogger(App.class);
    
    /**
     *The main method for RpcServerContainer application.
     * @param args Command line argument values.
     * @throws IOException if there is a problem with reading/writing app packages.
     */
    public static void main( String[] args ) throws IOException
    {
        final ExecutorService exectorService;
        
        final String appsDirFile;
        if (args.length ==1) {
            appsDirFile = args[0];
            log.debug("Apps directory configured to be: " + appsDirFile);
        } else {
            appsDirFile = "/Data/Apps";
            log.debug("Apps directory defaulting to: " + appsDirFile);
        }
        
        File appsDir = new File(appsDirFile);
        List<RpcPackage> packages = PackageReader.readPackages(appsDir);
        
        if (log.isDebugEnabled()) {
            log.debug("Start building TheadFactoryBuilder.");
        }
        
        ThreadFactoryBuilder builder = new ThreadFactoryBuilder();
        builder.setUncaughtExceptionHandler(new RpcServerUncaughtExceptionHandler());
        builder.setNameFormat("RpcServerContainer-%1$i");
        
        if (log.isDebugEnabled()) {
            log.debug("Built TheadFactoryBuilder. Creating executor service.");
        }
        
        exectorService = Executors.newFixedThreadPool(packages.size(), builder.build());
        
        if (log.isDebugEnabled()) {
            log.debug("Created executor service.");
        }
        
        for (PackageReader.RpcPackage item : packages) {
            
            if (log.isDebugEnabled()) {
                log.debug("Creating runnable for app: " + item.getName());
            }
            
            RpcPackageRunner runner = new RpcPackageRunner(item);
            
            if (log.isDebugEnabled()) {
                log.debug("Created runnable for app: " + item.getName() + ". Adding runnable to executor service.");
            }
            
            exectorService.execute(runner);
            
            if (log.isDebugEnabled()) {
                log.debug("App: " + item.getName() + " is loaded.");
            }
            
        }
    }
}
